from appium.webdriver.webdriver import WebDriver
from appium.webdriver.common.appiumby import AppiumBy as by
import time
import configparser
from os import path
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException


class Basepage:
    def __init__(self, driver: WebDriver = None):
        self.driver = driver
        # 读取 page.ini 配置文件
        self.config = configparser.ConfigParser()
        config_path = path.join(path.dirname(__file__), '..', 'page.ini')
        self.config.read(config_path, encoding='utf-8')

    def get_locator(self, section: str, option: str):
        if not self.config.has_section(section):
            raise ValueError(f"配置文件中不存在 [{section}] 区块")
        if not self.config.has_option(section, option):
            raise ValueError(f"配置文件 [{section}] 中不存在 '{option}' 元素")

        value = self.config.get(section, option)
        by_str, locator = value.split(',', 1)
        by_str = by_str.strip().lower()
        locator = locator.strip()

        by_map = {
            'id': by.ID,
            'xpath': by.XPATH,
            'uiautomator': by.ANDROID_UIAUTOMATOR,
            'accessibility': by.ACCESSIBILITY_ID,
            'class': by.CLASS_NAME,
        }

        if by_str not in by_map:
            raise ValueError(f"不支持的定位方式: {by_str}")

        return by_map[by_str], locator

    def wait_for_clickable(self, section: str, option: str, timeout=10):
        locator = self.get_locator(section, option)
        try:
            WebDriverWait(self.driver, timeout).until(
                EC.element_to_be_clickable(locator)
            )
        except TimeoutException:
            raise TimeoutException(f"元素 [{section}.{option}] 在 {timeout} 秒内不可点击")
        return self

    def wait_for_present(self, section: str, option: str, timeout=10):
        locator = self.get_locator(section, option)
        try:
            WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located(locator)
            )
        except TimeoutException:
            raise TimeoutException(f"元素 [{section}.{option}] 在 {timeout} 秒内未出现")
        return self

    def find_and_click(self, section: str, option: str):
        self.wait_for_clickable(section, option)
        self.driver.find_element(*self.get_locator(section, option)).click()
        return self

    def find_and_sendkeys(self, section: str, option: str, text: str):
        self.wait_for_present(section, option)
        el = self.driver.find_element(*self.get_locator(section, option))
        el.clear()
        el.send_keys(text)
        return self

    def find_and_get_text(self, section: str, option: str) -> str:
        self.wait_for_present(section, option)
        return self.driver.find_element(*self.get_locator(section, option)).text

    def find(self, section: str, option: str):
        self.wait_for_present(section, option)
        return self.driver.find_element(*self.get_locator(section, option))

    def get_test_data(self, option: str):
        section = 'TestData'
        if not self.config.has_section(section):
            raise ValueError(f"配置文件中不存在 [{section}] 区块")
        if not self.config.has_option(section, option):
            raise ValueError(f"配置文件 [{section}] 中不存在 '{option}' 数据")
        return self.config.get(section, option)

